﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Threading;

namespace PickGold.Callers
{
	/// <summary>
	/// 表示一或两个异步操作线程的同步事件。
	/// </summary>
	[ComVisible(true)]
	public class DoubleWaitHandle : EventWaitHandle
	{
		/// <summary>
		/// 继续: initialState = true
		/// </summary>
		public const bool CONTINUE = true;
		/// <summary>
		/// 终止: initialState = false
		/// </summary>
		public const bool PAUSE = false;

		private WaitHandle _WaitHandle;

		/// <summary>
		/// 初始化 AsyncResultWaitHandler 类的新实例。
		/// </summary>
		/// <param name="waitHandle">前置 WaitHandle 对象。</param>
		public DoubleWaitHandle(WaitHandle waitHandle)
			: base(false, EventResetMode.ManualReset)
		{
			this._WaitHandle = waitHandle;
		}

		/// <summary>
		/// 初始化 AsyncResultWaitHandler 类的新实例，并指定等待句柄最初是否处于终止状态。
		/// </summary>
		/// <param name="waitHandle">前置 WaitHandle 对象。</param>
		/// <param name="initialState">如果为 true，则将初始状态设置为终止；如果为 false，则将初始状态设置为非终止；默认为非终止。</param>
		public DoubleWaitHandle(WaitHandle waitHandle, bool initialState)
			: base(initialState, EventResetMode.ManualReset)
		{
			this._WaitHandle = waitHandle;
		}

		/// <summary>
		/// 初始化 AsyncResultWaitHandler 类的新实例，并指定等待句柄最初是否处于终止状态，以及它是自动重置还是手动重置。
		/// </summary>
		/// <param name="waitHandle">前置 WaitHandle 对象。</param>
		/// <param name="initialState">如果为 true，则将初始状态设置为终止；如果为 false，则将初始状态设置为非终止；默认为非终止。</param>
		/// <param name="mode">System.Threading.EventResetMode 值之一，它确定事件是自动重置还是手动重置，默认为手动重置。</param>
		public DoubleWaitHandle(WaitHandle waitHandle, bool initialState, EventResetMode mode)
			: base(initialState, mode)
		{
			this._WaitHandle = waitHandle;
		}

		/// <summary>
		/// 获取或设置前置 WaitHandle 对象。
		/// </summary>
		public WaitHandle WaitHandle
		{
			set
			{
				this._WaitHandle = value;
			}
			get
			{
				return this._WaitHandle;
			}
		}

		/// <summary>
		/// 阻止当前线程，直到当前 System.Threading.WaitHandle 收到信号。
		/// </summary>
		/// <returns>如果当前实例收到信号，则为 true。如果当前实例永远收不到信号，则 System.Threading.WaitHandle.WaitOne(System.Int32,System.Boolean) 永不返回。</returns>
		/// <exception cref="System.ObjectDisposedException">当前实例已被释放。</exception>
		/// <exception cref="System.Threading.AbandonedMutexException">线程退出时未释放互斥体，等待过程已终止。在 Windows 98 或 Windows Millennium Edition 中不引发此异常。</exception>
		/// <exception cref="System.InvalidOperationException">当前实例是另一个应用程序域中的 System.Threading.WaitHandle 的透明代理。</exception>
		public override bool WaitOne()
		{
			if (this._WaitHandle != null)
				return this._WaitHandle.WaitOne() && base.WaitOne();

			return base.WaitOne();
		}

		/// <summary>
		/// 阻止当前线程，直到当前 System.Threading.WaitHandle 收到信号，同时使用 32 位有符号整数测量时间间隔。
		/// </summary>
		/// <param name="millisecondsTimeout">等待的毫秒数，或为 System.Threading.Timeout.Infinite (-1)，表示无限期等待。</param>
		/// <returns>如果当前实例收到信号，则为 true；否则为 false。</returns>
		/// <exception cref="System.ObjectDisposedException">当前实例已被释放。</exception>
		/// <exception cref="System.ArgumentOutOfRangeException">millisecondsTimeout 是一个非 -1 的负数，而 -1 表示无限期超时。</exception>
		/// <exception cref="System.Threading.AbandonedMutexException">线程退出时未释放互斥体，等待过程已终止。在 Windows 98 或 Windows Millennium Edition 中不引发此异常。</exception>
		/// <exception cref="System.InvalidOperationException">当前实例是另一个应用程序域中的 System.Threading.WaitHandle 的透明代理。</exception>
		public override bool WaitOne(int millisecondsTimeout)
		{
			if (this._WaitHandle == null)
				return base.WaitOne(millisecondsTimeout);

			return WaitHandle.WaitAll(new WaitHandle[] { this._WaitHandle, this }, millisecondsTimeout);
		}

		/// <summary>
		/// 使用 32 位有符号整数度量时间间隔，并指定是否在等待之前退出同步域，以此阻止当前线程，直到当前的 System.Threading.WaitHandle 收到信号。
		/// </summary>
		/// <param name="millisecondsTimeout">等待的毫秒数，或为 System.Threading.Timeout.Infinite (-1)，表示无限期等待。</param>
		/// <param name="exitContext">如果等待之前先退出上下文的同步域（如果在同步上下文中），并在稍后重新获取它，则为 true；否则为 false。</param>
		/// <returns>如果当前实例收到信号，则为 true；否则为 false。</returns>
		/// <exception cref="System.ObjectDisposedException">当前实例已被释放。</exception>
		/// <exception cref="System.ArgumentOutOfRangeException">millisecondsTimeout 是一个非 -1 的负数，而 -1 表示无限期超时。</exception>
		/// <exception cref="System.Threading.AbandonedMutexException">线程退出时未释放互斥体，等待过程已终止。在 Windows 98 或 Windows Millennium Edition 中不引发此异常。</exception>
		/// <exception cref="System.InvalidOperationException">当前实例是另一个应用程序域中的 System.Threading.WaitHandle 的透明代理。</exception>
		public override bool WaitOne(int millisecondsTimeout, bool exitContext)
		{
			if (this._WaitHandle == null)
				return base.WaitOne(millisecondsTimeout, exitContext);

			return WaitHandle.WaitAll(new WaitHandle[] { this._WaitHandle, this }, millisecondsTimeout, exitContext);
		}

		/// <summary>
		/// 阻止当前线程，直到当前实例收到信号，同时使用 System.TimeSpan 测量时间间隔。
		/// </summary>
		/// <param name="timeout">表示等待的毫秒数的 System.TimeSpan，或表示 -1 毫秒（无限期等待）的 System.TimeSpan。</param>
		/// <returns>如果当前实例收到信号，则为 true；否则为 false。</returns>
		/// <exception cref="System.ObjectDisposedException">当前实例已被释放。</exception>
		/// <exception cref="System.ArgumentOutOfRangeException">timeout 是一个非 -1 毫秒的负数，而 -1 表示无限期超时。 - 或 - timeout 大于 System.Int32.MaxValue。</exception>
		/// <exception cref="System.Threading.AbandonedMutexException">线程退出时未释放互斥体，等待过程已终止。在 Windows 98 或 Windows Millennium Edition 中不引发此异常。</exception>
		/// <exception cref="System.InvalidOperationException">当前实例是另一个应用程序域中的 System.Threading.WaitHandle 的透明代理。</exception>
		public override bool WaitOne(TimeSpan timeout)
		{
			if (this._WaitHandle == null)
				return base.WaitOne(timeout);

			return WaitHandle.WaitAll(new WaitHandle[] { this._WaitHandle, this }, timeout);
		}

		/// <summary>
		/// 使用 System.TimeSpan 度量时间间隔并指定是否在等待之前退出同步域，以此阻止当前线程，直到当前的实例收到信号。
		/// </summary>
		/// <param name="timeout">表示等待的毫秒数的 System.TimeSpan，或表示 -1 毫秒（无限期等待）的 System.TimeSpan。</param>
		/// <param name="exitContext">如果等待之前先退出上下文的同步域（如果在同步上下文中），并在稍后重新获取它，则为 true；否则为 false。</param>
		/// <returns>如果当前实例收到信号，则为 true；否则为 false。</returns>
		/// <exception cref="System.ObjectDisposedException">当前实例已被释放。</exception>
		/// <exception cref="System.ArgumentOutOfRangeException">timeout 是一个非 -1 毫秒的负数，而 -1 表示无限期超时。 - 或 - timeout 大于 System.Int32.MaxValue。</exception>
		/// <exception cref="System.Threading.AbandonedMutexException">线程退出时未释放互斥体，等待过程已终止。在 Windows 98 或 Windows Millennium Edition 中不引发此异常。</exception>
		/// <exception cref="System.InvalidOperationException">当前实例是另一个应用程序域中的 System.Threading.WaitHandle 的透明代理。</exception>
		public override bool WaitOne(TimeSpan timeout, bool exitContext)
		{
			if (this._WaitHandle == null)
				return base.WaitOne(timeout, exitContext);

			return WaitHandle.WaitAll(new WaitHandle[] { this._WaitHandle, this }, timeout, exitContext);
		}
	}
}
